package com.lingz.manager.modules.base.serviceimpl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lingz.manager.common.constant.CommonConstant;
import com.lingz.manager.common.utils.FileUtil;
import com.lingz.manager.common.utils.FileUtils;
import com.lingz.manager.common.utils.ResultUtil;
import com.lingz.manager.common.vo.Result;
import com.lingz.manager.common.vo.SearchVo;
import com.lingz.manager.modules.base.dao.FileDao;
import com.lingz.manager.modules.base.dao.mapper.FileMapper;
import com.lingz.manager.modules.base.entity.File;
import com.lingz.manager.modules.base.entity.FileBySys;
import com.lingz.manager.modules.base.service.FileService;
import com.lingz.manager.modules.base.vo.OssSetting;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.*;
import java.util.*;

/**
 * 文件管理接口实现
 * @author Exrick
 */
@Slf4j
@Service
@Transactional
public class FileServiceImpl implements FileService {

    @Autowired
    private FileDao fileDao;

    @Override
    public FileDao getRepository() {
        return fileDao;
    }

    @Autowired
    private FileMapper fileMapper;

    @Override
    public Page<FileBySys> findByCondition(FileBySys file, SearchVo searchVo, Pageable pageable) {

        return fileDao.findAll(new Specification<FileBySys>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<FileBySys> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                Path<String> nameField = root.get("name");
                Path<String> fKeyField = root.get("fKey");
                Path<String> typeField = root.get("type");
                Path<Integer> locationField = root.get("location");
                Path<Date> createTimeField=root.get("createTime");
                Path<String> taskIdField = root.get("taskId");
                Path<String> random = root.get("random");
                List<Predicate> list = new ArrayList<Predicate>();

                //模糊搜素
                if(StrUtil.isNotBlank(file.getName())){
                    list.add(cb.like(nameField,'%'+file.getName()+'%'));
                }
                if(StrUtil.isNotBlank(file.getFKey())){
                    list.add(cb.like(fKeyField,'%'+file.getFKey()+'%'));
                }
                if(StrUtil.isNotBlank(file.getType())){
                    list.add(cb.like(typeField,'%'+file.getType()+'%'));
                }
                if(StrUtil.isNotBlank(file.getTaskId())){
                    list.add(cb.equal(taskIdField,file.getTaskId()));
                }
                if(StrUtil.isNotBlank(file.getRandom())){
                    list.add(cb.equal(random,file.getRandom()));
                }
                if(file.getLocation()!=null){
                    list.add(cb.equal(locationField, file.getLocation()));
                }

                //创建时间
                if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                }
                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));

                //  排序  add 2021/11/3 lww
                Order createTime = cb.desc(root.get("createTime"));
                cq.orderBy(createTime);
                return cq.getRestriction();
            }
        }, pageable);
    }
    public List<FileBySys> findByCondition(FileBySys file, SearchVo searchVo) {

        return fileDao.findAll(new Specification<FileBySys>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<FileBySys> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                Path<String> nameField = root.get("name");
                Path<String> fKeyField = root.get("fKey");
                Path<String> typeField = root.get("type");
                Path<Integer> locationField = root.get("location");
                Path<Date> createTimeField=root.get("createTime");
                Path<String> taskIdField = root.get("taskId");
                Path<String> random = root.get("random");
                List<Predicate> list = new ArrayList<Predicate>();

                //模糊搜素
                if(StrUtil.isNotBlank(file.getName())){
                    list.add(cb.like(nameField,'%'+file.getName()+'%'));
                }
                if(StrUtil.isNotBlank(file.getFKey())){
                    list.add(cb.like(fKeyField,'%'+file.getFKey()+'%'));
                }
                if(StrUtil.isNotBlank(file.getType())){
                    list.add(cb.like(typeField,'%'+file.getType()+'%'));
                }
                if(StrUtil.isNotBlank(file.getTaskId())){
                    list.add(cb.equal(taskIdField,file.getTaskId()));
                }
                if(StrUtil.isNotBlank(file.getRandom())){
                    list.add(cb.equal(random,file.getRandom()));
                }
                if(file.getLocation()!=null){
                    list.add(cb.equal(locationField, file.getLocation()));
                }

                //创建时间
                if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                }

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr)).orderBy(cb.asc(createTimeField));
                return null;
            }
        });
    }

    @Override
    public int countByTaskIdAndRandom(String taskId, String random) {
        return fileDao.countByTaskIdAndRandom(taskId,random);
    }

    @Override
    public FileBySys findById(String id) {
        Optional<FileBySys> optionalFile = fileDao.findById(id);
        if(optionalFile.isPresent()){
            return optionalFile.get();
        }
        return null;
    }

    @Override
    public void delFileByTaskId(String[] taskIds) {
        if(taskIds.length<=0){
            return;
        }
        //获取文件信息
        LambdaQueryWrapper<FileBySys> wrapper = Wrappers.lambdaQuery(FileBySys.class);
        wrapper.in(FileBySys::getTaskId,Arrays.asList(taskIds.clone()));
        List<FileBySys> list = fileMapper.selectList(wrapper);
        for (FileBySys fileBySys : list) {
            try {
                //删除本地文件
                FileUtils.deleteDir(fileBySys.getLocationUrl());
                //删除数据库数据
                fileMapper.deleteById(fileBySys);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public String deleteFileInfoByIds(String[] ids) {
        LambdaQueryWrapper<FileBySys> wrapper = Wrappers.lambdaQuery(FileBySys.class);
        wrapper.in(FileBySys::getId,ids);
        List<FileBySys> list = fileMapper.selectList(wrapper);
        fileMapper.deleteBatchIds(Arrays.asList(ids));
        for (FileBySys file : list) {
            try {
                //删除本地文件
                FileUtils.deleteDir(file.getLocationUrl());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "操作成功";
    }

    @Override
    public Result<String> updateFileName(FileBySys file) {
        int updateById = fileMapper.updateById(file);

        return updateById>0?new ResultUtil<String>().setData("修改成功！"):new ResultUtil<String>().setErrorMsg("修改失败！");
    }
}